const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const AddAssetHtmlPlugin = require("add-asset-html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const {BundleAnalyzerPlugin} = require("webpack-bundle-analyzer")
const webpack = require("webpack");

const { getStyleLoaders, tsLoader, getUrlLoader } = require("../utils");
const { distPath,basePath } = require("../config");
const { loader } = require("mini-css-extract-plugin");
const moduleRegex = /(node_modules)|(dist\\)/;
const dllPath = path.resolve(distPath, "dll");
const entryPath = path.resolve(__dirname, "../../index.js");
const templateHTML = path.resolve(__dirname, "../../index.html");
let isDev = process.env.NODE_ENV == "development" ? true : false;

let config = {
  entry: {
    index: entryPath,
  },
  output: {
    path: distPath,
    filename: isDev ? "[name].js" : "[name].[hash:8].js",
    chunkFilename: isDev
      ? "bundles/[name].js"
      : "bundles/[name].[contenthash:8].js",
    publicPath: basePath,
  },
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "../../"),
      "~": distPath,
    },
    extensions: [".jsx", ".js", ".tsx", ".ts", ".json"],
  },
  optimization: {
    splitChunks: {
      chunks: "all", //all/initial/async
      minSize: 30000, //代码块的最小尺寸30kb
      minChunks: 1, //被多少模块共享,在分割之前模块的被引用次数
      maxAsyncRequests: 5, //按需加载最大并行请求数量
      maxInitialRequests: 3, //一个入口的最大并行请求数量
      name: true, //打包后的名称，默认是chunk的名字通过分隔符（默认是～）分隔开，如vendor~
      automaticNameDelimiter: "~", //默认webpack将会使用入口名和代码块的名称生成命名,比如 'vendors~main.js'
      cacheGroups: {
        //设置缓存组用来抽取满足不同规则的chunk,下面以生成common为例
        vendors: {
          // name: "vendors", // 显示vendor~index更友好一点
          test: /node_modules/, //条件
          priority: -10, ///优先级，一个chunk很可能满足多个缓存组，会被抽取到优先级高的缓存组中,为了能够让自定义缓存组有更高的优先级(默认0),默认缓存组的priority属性为负值.
        },
        commons: {
          minSize: 0, //最小提取字节数
          minChunks: 2, //最少被几个chunk引用
          priority: -20,
          reuseExistingChunk: true, //    如果该chunk中引用了已经被抽取的chunk，直接引用该chunk，不会重复打包代码
        },
      },
    },
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: moduleRegex, // js处理排除node_modules和libs
        use: ["babel-loader"],
      },
      {
        test: /\.tsx?$/,
        exclude: moduleRegex, // js处理排除node_modules和libs
        use: ["babel-loader", tsLoader],
      },
      {
        // 源码就转语法树
        test: /\.css$/,
        exclude: moduleRegex,
        use: getStyleLoaders(true),
      },
      {
        // 三方样式就不转语法树
        test: /\.css$/,
        include: moduleRegex,
        use: getStyleLoaders(false),
      },
      {
        test: /\.less$/, // less只在源码里面写，三方包就用css避免重复打包
        exclude: moduleRegex,
        use: getStyleLoaders(true, {}, "less-loader"),
      },
      {
        test: /\.(jpg|png|gif|jpeg)$/, //处理图片,把图片打包到输出目录中
        loader: getUrlLoader(),
      },
      {
        test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
        loader: getUrlLoader(true),
      },
    ],
  },
  plugins: [
    new CleanWebpackPlugin({
      // dry: true,
      // verbose: true,
      cleanStaleWebpackAssets: false,
      protectWebpackAssets: false,
      cleanOnceBeforeBuildPatterns: [
        "*.js",
        "*.css",
        "*.map",
        "*.json",
        "bundles/**/*",
      ],
    }),
    new MiniCssExtractPlugin({
      filename: isDev ? "styles/[name].css" : "styles/[name].[hash:8].css", // 坑点:filename只能配[hash]
      chunkFilename: isDev
        ? "styles/[name].css"
        : "styles/[name].[contenthash:8].css",
      ignoreOrder: true, //  启用以删除有关顺序冲突的警告
    }),
    new HtmlWebpackPlugin({
      template: templateHTML,
    }),
    new webpack.DllReferencePlugin({
      manifest: require(path.resolve(dllPath, "react_manifest.json")),
    }),
    new AddAssetHtmlPlugin({ filepath: path.resolve(dllPath, "*.dll.js") }),
    // 分析bundle
    // new BundleAnalyzerPlugin({
    //   openAnalyzer: false,
    // }),
  ],
  performance: {
    maxAssetSize: 1.5 * 1024 * 1024, //默认值：250000 (bytes)
    maxEntrypointSize: 1.5 * 1024 * 1024,
  },
};

module.exports = config;
